package org.timeismoney.payment.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.timeismoney.payment.dao.PaymentRecordDao;
import org.timeismoney.payment.exception.BizException;
import org.timeismoney.payment.model.ItemPaymentDetail;
import org.timeismoney.payment.model.PaymentFin;
import org.timeismoney.payment.model.PaymentRecord;
import org.timeismoney.payment.service.ItemStuDetailService;
import org.timeismoney.payment.service.PaymentFinService;
import org.timeismoney.payment.service.PaymentRecordService;

public class PaymentRecordServiceImpl extends BaseServiceImpl<PaymentRecord, Integer> implements
		PaymentRecordService {
	private ItemStuDetailService stuDetailService;
	private PaymentFinService finService;
	
	public void setStuDetailService(ItemStuDetailService stuDetailService) {
		this.stuDetailService = stuDetailService;
	}

	public void setFinService(PaymentFinService finService) {
		this.finService = finService;
	}
	
	public BigDecimal getTotalPaySuccessByStuNoAndYearNo(String stuNo, Integer yearNo) {
		return ((PaymentRecordDao)getDao()).getTotalPaySuccessByStuNoAndYearNo(stuNo,yearNo);
	}

	public void finish(String paymentRecordNo, BigDecimal cost) {
		Date now = new Date();
		List<PaymentRecord> list = getDao().findByExample(new PaymentRecord(paymentRecordNo,false));
		if(list.size()>0){
			PaymentRecord temp = list.get(0);
			if (temp!=null) {
				List<ItemPaymentDetail> details = stuDetailService.findItemPaymentByStu(temp.getStudent().getStuNo(), temp.getSchoolYear().getSchoolYearNo());
				BigDecimal recordsAmount = new BigDecimal(0);
				BigDecimal detailsAmount = new BigDecimal(0);
				for (ItemPaymentDetail itemPaymentDetail : details) {
					detailsAmount = detailsAmount.add(itemPaymentDetail.getCost());		
				}
				for (PaymentRecord paymentRecord : list) {
					recordsAmount = recordsAmount.add(paymentRecord.getPayment());
				}
				if (recordsAmount.compareTo(cost) > 0) {
					throw new BizException("转账单金额为："+recordsAmount.doubleValue()+",请确认银行转账金额！");
				}
				((PaymentRecordDao)getDao()).batchUpdateRecords(paymentRecordNo,now);

				//find paid amt
				BigDecimal paidAmt = getTotalPaySuccessByStuNoAndYearNo(temp.getStudent().getStuNo(), temp.getSchoolYear().getSchoolYearNo());
				PaymentFin uniqueFin4Year = finService.getFinsByStuNoAndYearNo(temp.getStudent().getStuNo(), temp.getSchoolYear().getSchoolYearNo());
				if (paidAmt.compareTo(detailsAmount) >= 0) {
					if (uniqueFin4Year != null) {
						uniqueFin4Year.setDatetime(now);
						uniqueFin4Year.setTotal(paidAmt);
						finService.update(uniqueFin4Year);
					} else {
						PaymentFin fin = new PaymentFin();
						fin.setStudent(temp.getStudent());
						fin.setSchoolYear(temp.getSchoolYear());
						fin.setDatetime(now);
						fin.setTotal(paidAmt);
						finService.save(fin);
					}
				} else {
					if (uniqueFin4Year != null) {
						finService.delete(uniqueFin4Year);
					}
				}
			}
		}else{
			throw new BizException("查无此转账单，或已支付。");
		}
	}

	public void createOrder(List<PaymentRecord> records, PaymentRecord finRecord) {
		List<PaymentRecord> payments = new ArrayList<PaymentRecord>();
		BigDecimal zero = new BigDecimal(0);
		BigDecimal finCost = new BigDecimal(0);
		if(finRecord!=null){
			finCost = finRecord.getPayment().multiply(new BigDecimal(-1));
		}
		for (PaymentRecord paymentRecord : records) {
			
			if (finCost.doubleValue()!=0) {
				if (paymentRecord.getPayment().compareTo(finCost) >= 0) {
					paymentRecord.setPayment(paymentRecord.getPayment()
							.subtract(finCost));
					finCost = zero;
				} else {
					finCost = finCost.subtract(paymentRecord.getPayment());
					paymentRecord.setPayment(zero);
				}
			}
			if (paymentRecord.getPayment().doubleValue()!=0) {
				payments.add(paymentRecord);
			}
		}
		if(payments.size()>0){
			((PaymentRecordDao)getDao()).batchInsertRecords(payments);
		}
	}

	public void deleteByStuNo(String stuNo) {
		((PaymentRecordDao)getDao()).deleteByStuNo(stuNo);
	}

	public void deleteByItemPaymentNo(int itemPaymentNo) {
		((PaymentRecordDao)getDao()).deleteByItemPaymentNo(itemPaymentNo);
	}

	public void deleteBySchoolYearNo(Integer schoolYearNo) {
		((PaymentRecordDao) getDao()).deleteBySchoolYearNo(schoolYearNo);
	}

	public void deleteByItemNo(Integer itemNo) {
		((PaymentRecordDao) getDao()).deleteByItemNo(itemNo);
	}

	public List<PaymentRecord> findPaymentRecordByItemPaymentDetail(
			ItemPaymentDetail detail) {
		return getDao().find("from PaymentRecord where success=true and schoolYear=? and itemPaymentDetail=?", detail.getSchoolYear(),detail);
	}

}
